{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50ca85de",
   "metadata": {},
   "outputs": [],
   "source": [
    "import osmnx as ox\n",
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt #installs with osmnx\n",
    "import pandas as pd\n",
    "%matplotlib inline\n",
    "ox.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a56733ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the network for Piedmont, calculate its basic stats, then show the average circuity\n",
    "stats = ox.basic_stats(ox.graph_from_place(\"Paris, France\"))\n",
    "stats[\"circuity_avg\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e5c7bf59",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the street network for a place, and its area in square meters\n",
    "place = \"Paris, France\"\n",
    "gdf = ox.geocode_to_gdf(place)\n",
    "area = ox.project_gdf(gdf).unary_union.area\n",
    "G = ox.graph_from_place(place, network_type=\"drive\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1661768a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# calculate basic and extended network stats, merge them together, and display\n",
    "stats = ox.basic_stats(G, area=area)\n",
    "pd.Series(stats)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ef23f9b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# unpack dicts into individiual keys:values\n",
    "stats = ox.basic_stats(G, area=area)\n",
    "for k, count in stats[\"streets_per_node_counts\"].items():\n",
    "    stats[\"{}way_int_count\".format(k)] = count\n",
    "for k, proportion in stats[\"streets_per_node_proportions\"].items():\n",
    "    stats[\"{}way_int_prop\".format(k)] = proportion\n",
    "\n",
    "# delete the no longer needed dict elements\n",
    "del stats[\"streets_per_node_counts\"]\n",
    "del stats[\"streets_per_node_proportions\"]\n",
    "\n",
    "# load as a pandas dataframe\n",
    "pd.DataFrame(pd.Series(stats, name=\"value\")).round(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0afcba3f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# calculate betweenness with a digraph of G (ie, no parallel edges)\n",
    "bc = nx.betweenness_centrality(ox.get_digraph(G), weight=\"length\")\n",
    "max_node, max_bc = max(bc.items(), key=lambda x: x[1])\n",
    "max_node, max_bc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a274b91",
   "metadata": {},
   "outputs": [],
   "source": [
    "nc = [\"r\" if node == max_node else \"grey\" for node in G.nodes]\n",
    "ns = [100 if node == max_node else 15 for node in G.nodes]\n",
    "fig, ax = ox.plot_graph(G, node_size=ns, node_color=nc, node_zorder=5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b2ed1ae",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# add the betweenness centraliy values as new node attributes, then plot\n",
    "nx.set_node_attributes(G, bc, \"bc\")\n",
    "nc = ox.plot.get_node_colors_by_attr(G, \"bc\", cmap=\"plasma\")\n",
    "fig, ax = ox.plot_graph(\n",
    "    G,\n",
    "    node_color=nc,\n",
    "    node_size=30,\n",
    "    node_zorder=2,\n",
    "    edge_linewidth=0.2,\n",
    "    edge_color=\"w\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f5bdf42c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the network for Piedmont, calculate its basic stats, then show the average circuity\n",
    "stats = ox.basic_stats(ox.graph_from_place(\"Manhattan,New York,United States\"))\n",
    "stats[\"circuity_avg\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6db6428e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the network for Piedmont, calculate its basic stats, then show the average circuity\n",
    "stats = ox.basic_stats(ox.graph_from_place(\"Washington DC, USA\"))\n",
    "stats[\"circuity_avg\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "05782d5b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the street network for a place, and its area in square meters\n",
    "place = \"Washington DC, USA\"\n",
    "gdf = ox.geocode_to_gdf(place)\n",
    "area = ox.project_gdf(gdf).unary_union.area\n",
    "G = ox.graph_from_place(place, network_type=\"drive\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5f50f83",
   "metadata": {},
   "outputs": [],
   "source": [
    "# calculate basic and extended network stats, merge them together, and display\n",
    "stats = ox.basic_stats(G, area=area)\n",
    "pd.Series(stats)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc1225d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# unpack dicts into individiual keys:values\n",
    "stats = ox.basic_stats(G, area=area)\n",
    "for k, count in stats[\"streets_per_node_counts\"].items():\n",
    "    stats[\"{}way_int_count\".format(k)] = count\n",
    "for k, proportion in stats[\"streets_per_node_proportions\"].items():\n",
    "    stats[\"{}way_int_prop\".format(k)] = proportion\n",
    "\n",
    "# delete the no longer needed dict elements\n",
    "del stats[\"streets_per_node_counts\"]\n",
    "del stats[\"streets_per_node_proportions\"]\n",
    "\n",
    "# load as a pandas dataframe\n",
    "pd.DataFrame(pd.Series(stats, name=\"value\")).round(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a1229977",
   "metadata": {},
   "outputs": [],
   "source": [
    "# calculate betweenness with a digraph of G (ie, no parallel edges)\n",
    "bc = nx.betweenness_centrality(ox.get_digraph(G), weight=\"length\")\n",
    "max_node, max_bc = max(bc.items(), key=lambda x: x[1])\n",
    "max_node, max_bc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bfdd0dbd",
   "metadata": {},
   "outputs": [],
   "source": [
    "nc = [\"r\" if node == max_node else \"w\" for node in G.nodes]\n",
    "ns = [80 if node == max_node else 15 for node in G.nodes]\n",
    "fig, ax = ox.plot_graph(G, node_size=ns, node_color=nc, node_zorder=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc0199e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# add the betweenness centraliy values as new node attributes, then plot\n",
    "nx.set_node_attributes(G, bc, \"bc\")\n",
    "nc = ox.plot.get_node_colors_by_attr(G, \"bc\", cmap=\"plasma\")\n",
    "fig, ax = ox.plot_graph(\n",
    "    G,\n",
    "    node_color=nc,\n",
    "    node_size=30,\n",
    "    node_zorder=2,\n",
    "    edge_linewidth=0.2,\n",
    "    edge_color=\"w\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4a63edab",
   "metadata": {},
   "outputs": [],
   "source": [
    "# download/model a street network for some city then visualize it\n",
    "G = ox.graph_from_place(\"Los Angeles,California,United States\", network_type=\"drive\")\n",
    "fig, ax = ox.plot_graph(G,figsize=(20,20),bgcolor='#FFFFFF',\n",
    "    node_color='black', node_size=0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c10b4e86",
   "metadata": {},
   "outputs": [],
   "source": [
    "ox.speed.add_edge_speeds(G, hwy_speeds=None, fallback=None, precision=1)\n",
    "ox.speed.add_edge_travel_times(G, precision=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c5c34a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "G = ox.add_edge_speeds(G)\n",
    "G = ox.add_edge_travel_times(G)\n",
    "\n",
    "w = 'travel_time'\n",
    "orig, dest = list(G)[10], list(G)[-10]\n",
    "route1 = nx.shortest_path(G, orig, dest, weight=w)\n",
    "orig, dest = list(G)[0], list(G)[-1]\n",
    "route2 = nx.shortest_path(G, orig, dest, weight=w)\n",
    "orig, dest = list(G)[-100], list(G)[100]\n",
    "route3 = nx.shortest_path(G, orig, dest, weight=w)\n",
    "\n",
    "routes = [route1, route2, route3]\n",
    "rc = ['r', 'y', 'c']\n",
    "fig, ax = ox.plot_graph_routes(G, routes, route_colors=rc, route_linewidth=6, figsize=(30, 30),node_size=0,bgcolor='#FFFFFF')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7bd5399c",
   "metadata": {},
   "outputs": [],
   "source": [
    "place_name = 'Culver City, California, United States'\n",
    "G = ox.graph_from_place(place_name, clean_periphery=False,network_type=\"all_private\")\n",
    "fig, ax = ox.plot_graph(G,figsize=(7,7),bgcolor='#FFFFFF',\n",
    "     node_color=\"b\",node_size=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b35867e",
   "metadata": {},
   "outputs": [],
   "source": [
    "place_name = 'Washington DC, United States'\n",
    "G = ox.graph_from_place(place_name, clean_periphery=False,network_type=\"all_private\")\n",
    "fig, ax = ox.plot_graph(G,figsize=(7,7),bgcolor='#FFFFFF',\n",
    "     node_color=\"b\",node_size=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1d6fd896",
   "metadata": {},
   "outputs": [],
   "source": [
    "place_name = \"Culver City, California, United States\"\n",
    "graph = ox.graph_from_place(place_name, network_type='drive')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "26d31042",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = ox.plot_graph(graph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be665973",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Retrieve only edges from the graph\n",
    "edges = ox.graph_to_gdfs(graph, nodes=False, edges=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d129310",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check columns\n",
    "edges.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b5b4f46",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check crs\n",
    "edges.crs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90734a43",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "edges.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f3676e48",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(edges['highway'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3db6195",
   "metadata": {},
   "outputs": [],
   "source": [
    "graph_proj = ox.project_graph(graph)\n",
    "fig, ax = ox.plot_graph(graph_proj)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7af7917",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get Edges and Nodes\n",
    "nodes_proj, edges_proj = ox.graph_to_gdfs(graph_proj, nodes=True, edges=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7bbd252b",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Coordinate system:\", edges_proj.crs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "614c06c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "edges_proj.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a3aa48a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyproj import CRS\n",
    "CRS(edges_proj.crs).to_epsg()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bcd30522",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d78ff0b2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c485c68",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the Convex Hull of the network\n",
    "convex_hull = edges_proj.unary_union.convex_hull\n",
    "# Show output\n",
    "convex_hull\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97dab8bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate the area\n",
    "area = convex_hull.area\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4218bf9b",
   "metadata": {},
   "outputs": [],
   "source": [
    "G_proj = ox.project_graph(G)\n",
    "nodes_proj = ox.graph_to_gdfs(G_proj, edges=False)\n",
    "graph_area_m = nodes_proj.unary_union.convex_hull.area\n",
    "graph_area_m\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "558f3d0d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# show some basic stats about the network\n",
    "ox.basic_stats(G_proj, area=graph_area_m, clean_int_tol=15)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8b661f1b",
   "metadata": {},
   "outputs": [],
   "source": [
    "place = \"Culver City, California\"\n",
    "tags = {\"building\": True}\n",
    "gdf = ox.geometries_from_place(place, tags={'building':True})\n",
    "gdf.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b68d4a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get all building footprints in some neighborhood\n",
    "place = \"Culver City, California\"\n",
    "tags = {\"building\": True}\n",
    "gdf = ox.geometries_from_place(place, tags)\n",
    "gdf.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5876f9f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "fig, ax = ox.plot_footprints(gdf, figsize=(10, 10),bgcolor='#FFFFFF')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e833f586",
   "metadata": {},
   "outputs": [],
   "source": [
    "gdf=ox.geometries.geometries_from_address((52.3716,4.9005),dist=15000, tags={'natural':'water','highway':''})\n",
    "gdf.to_crs(epsg=28992, inplace=True)\n",
    "gdf.plot(figsize=(16,16))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ae86c1c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get everything tagged amenity,\n",
    "# and everything tagged landuse = retail or commercial,\n",
    "# and everything tagged highway = bus_stop\n",
    "tags = {\"amenity\": True, \"landuse\": [\"retail\", \"commercial\"], \"highway\": \"bus_stop\"}\n",
    "gdf = ox.geometries_from_place(\"Culver City, California, USA\", tags)\n",
    "gdf.shape\n",
    "gdf.plot(figsize=(20,29))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1f38fa3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# view just the banks\n",
    "gdf[gdf[\"amenity\"] == \"bank\"].dropna(axis=1, how=\"any\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b00e02f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# view just the bus stops\n",
    "gdf[gdf[\"highway\"] == \"bus_stop\"].dropna(axis=1, how=\"any\").head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "af477cc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import networkx as nx\n",
    "import osmnx as ox\n",
    "from IPython.display import IFrame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7d34c72e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot the street network with folium\n",
    "m1 = ox.plot_graph_folium(G, popup_attribute=\"name\", weight=2, color=\"#8b0000\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84073709",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# save as html file then display map as an iframe\n",
    "filepath = \"data/graph.html\"\n",
    "m1.save(filepath)\n",
    "IFrame(filepath, width=600, height=500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19c3690e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get all the building footprints in a city\n",
    "gdf = ox.geometries_from_place(\"Culver City, California, USA\", {\"building\": True})\n",
    "gdf.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1eb0d0ab",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = ox.plot_footprints(gdf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fdee8237",
   "metadata": {},
   "outputs": [],
   "source": [
    "# or plot street network and the entities' footprints together\n",
    "fig, ax = ox.plot_footprints(gdf, alpha=0.4, show=False)\n",
    "fig, ax = ox.plot_graph(G, ax=ax, node_size=0, edge_color=\"w\", edge_linewidth=0.7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f46d7e44",
   "metadata": {},
   "outputs": [],
   "source": [
    "import geopandas as gpd\n",
    "import matplotlib.pyplot as plt\n",
    "import networkx as nx\n",
    "import osmnx as ox\n",
    "from descartes import PolygonPatch\n",
    "from shapely.geometry import LineString\n",
    "from shapely.geometry import Point\n",
    "from shapely.geometry import Polygon\n",
    "\n",
    "%matplotlib inline\n",
    "ox.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d10f63fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "# configure the place, network type, trip times, and travel speed\n",
    "place = {\"city\": \"Culver City\", \"state\": \"California\"}\n",
    "network_type = \"walk\"\n",
    "trip_times = [5, 10, 15, 20, 25]  # in minutes\n",
    "travel_speed = 4.5  # walking speed in km/hour"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "038e522a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# download the street network\n",
    "G = ox.graph_from_place(place, network_type=network_type)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f7e04a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# find the centermost node and then project the graph to UTM\n",
    "gdf_nodes = ox.graph_to_gdfs(G, edges=False)\n",
    "x, y = gdf_nodes[\"geometry\"].unary_union.centroid.xy\n",
    "center_node = ox.distance.nearest_nodes(G, x[0], y[0])\n",
    "G = ox.project_graph(G)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6ab7b4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# add an edge attribute for time in minutes required to traverse each edge\n",
    "meters_per_minute = travel_speed * 1000 / 60  # km per hour to m per minute\n",
    "for _, _, _, data in G.edges(data=True, keys=True):\n",
    "    data[\"time\"] = data[\"length\"] / meters_per_minute"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21e2f456",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get one color for each isochrone\n",
    "iso_colors = ox.plot.get_colors(n=len(trip_times), cmap=\"plasma\", start=0, return_hex=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb04aadc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# color the nodes according to isochrone then plot the street network\n",
    "node_colors = {}\n",
    "for trip_time, color in zip(sorted(trip_times, reverse=True), iso_colors):\n",
    "    subgraph = nx.ego_graph(G, center_node, radius=trip_time, distance=\"time\")\n",
    "    for node in subgraph.nodes():\n",
    "        node_colors[node] = color\n",
    "nc = [node_colors[node] if node in node_colors else \"none\" for node in G.nodes()]\n",
    "ns = [15 if node in node_colors else 0 for node in G.nodes()]\n",
    "fig, ax = ox.plot_graph(\n",
    "    G,\n",
    "    node_color=nc,\n",
    "    node_size=ns,\n",
    "    node_alpha=0.8,\n",
    "    edge_linewidth=0.2,\n",
    "    edge_color=\"#999999\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e19e247",
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_iso_polys(G, edge_buff=25, node_buff=50, infill=False):\n",
    "    isochrone_polys = []\n",
    "    for trip_time in sorted(trip_times, reverse=True):\n",
    "        subgraph = nx.ego_graph(G, center_node, radius=trip_time, distance=\"time\")\n",
    "\n",
    "        node_points = [Point((data[\"x\"], data[\"y\"])) for node, data in subgraph.nodes(data=True)]\n",
    "        nodes_gdf = gpd.GeoDataFrame({\"id\": list(subgraph.nodes)}, geometry=node_points)\n",
    "        nodes_gdf = nodes_gdf.set_index(\"id\")\n",
    "\n",
    "        edge_lines = []\n",
    "        for n_fr, n_to in subgraph.edges():\n",
    "            f = nodes_gdf.loc[n_fr].geometry\n",
    "            t = nodes_gdf.loc[n_to].geometry\n",
    "            edge_lookup = G.get_edge_data(n_fr, n_to)[0].get(\"geometry\", LineString([f, t]))\n",
    "            edge_lines.append(edge_lookup)\n",
    "\n",
    "        n = nodes_gdf.buffer(node_buff).geometry\n",
    "        e = gpd.GeoSeries(edge_lines).buffer(edge_buff).geometry\n",
    "        all_gs = list(n) + list(e)\n",
    "        new_iso = gpd.GeoSeries(all_gs).unary_union\n",
    "\n",
    "        # try to fill in surrounded areas so shapes will appear solid and\n",
    "        # blocks without white space inside them\n",
    "        if infill:\n",
    "            new_iso = Polygon(new_iso.exterior)\n",
    "        isochrone_polys.append(new_iso)\n",
    "    return isochrone_polys\n",
    "\n",
    "\n",
    "isochrone_polys = make_iso_polys(G, edge_buff=25, node_buff=0, infill=True)\n",
    "fig, ax = ox.plot_graph(\n",
    "    G, show=False, close=False, edge_color=\"#999999\", edge_alpha=0.2, node_size=0\n",
    ")\n",
    "for polygon, fc in zip(isochrone_polys, iso_colors):\n",
    "    patch = PolygonPatch(polygon, fc=fc, ec=\"none\", alpha=0.7, zorder=-1)\n",
    "    ax.add_patch(patch)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "007046c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# make the isochrone polygons\n",
    "isochrone_polys = []\n",
    "for trip_time in sorted(trip_times, reverse=True):\n",
    "    subgraph = nx.ego_graph(G, center_node, radius=trip_time, distance=\"time\")\n",
    "    node_points = [Point((data[\"x\"], data[\"y\"])) for node, data in subgraph.nodes(data=True)]\n",
    "    bounding_poly = gpd.GeoSeries(node_points).unary_union.convex_hull\n",
    "    isochrone_polys.append(bounding_poly)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2ef4842",
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot the network then add isochrones as colored descartes polygon patches\n",
    "fig, ax = ox.plot_graph(\n",
    "    G, show=False, close=False, edge_color=\"#999999\", edge_alpha=0.2, node_size=0\n",
    ")\n",
    "for polygon, fc in zip(isochrone_polys, iso_colors):\n",
    "    patch = PolygonPatch(polygon, fc=fc, ec=\"none\", alpha=0.6, zorder=-1)\n",
    "    ax.add_patch(patch)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b70edd9",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import osmnx as ox\n",
    "from descartes import PolygonPatch\n",
    "from shapely.geometry import MultiPolygon\n",
    "from shapely.geometry import Polygon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00b8812e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# get the place boundaries\n",
    "place = \"Seattle, Washington\"\n",
    "gdf = ox.geocode_to_gdf(place)\n",
    "\n",
    "# get the street network, with retain_all=True to retain all the disconnected islands' networks\n",
    "G = ox.graph_from_place(place, network_type=\"drive\", retain_all=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f64ba85b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot the network, but do not show it or close it yet\n",
    "fig, ax = ox.plot_graph(\n",
    "    G,\n",
    "    show=False,\n",
    "    close=False,\n",
    "    bgcolor=\"white\",\n",
    "    edge_color=\"w\",\n",
    "    edge_linewidth=0.3,\n",
    "    node_size=0,\n",
    ")\n",
    "\n",
    "# to this matplotlib axis, add the place shape as descartes polygon patches\n",
    "for geometry in gdf[\"geometry\"].tolist():\n",
    "    if isinstance(geometry, (Polygon, MultiPolygon)):\n",
    "        if isinstance(geometry, Polygon):\n",
    "            geometry = MultiPolygon([geometry])\n",
    "        for polygon in geometry.geoms:\n",
    "            patch = PolygonPatch(polygon, fc=\"k\", ec=\"#666666\", lw=1, alpha=1, zorder=-1)\n",
    "            ax.add_patch(patch)\n",
    "\n",
    "# optionally set up the axes extents\n",
    "margin = 0.02\n",
    "west, south, east, north = gdf.unary_union.bounds\n",
    "margin_ns = (north - south) * margin\n",
    "margin_ew = (east - west) * margin\n",
    "ax.set_ylim((south - margin_ns, north + margin_ns))\n",
    "ax.set_xlim((west - margin_ew, east + margin_ew))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c4a3ef16",
   "metadata": {},
   "outputs": [],
   "source": [
    "islands = ox.geometries_from_place(place, tags={\"place\": [\"island\", \"islet\"]})\n",
    "islands.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "91b2c706",
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f11c5ee6",
   "metadata": {},
   "outputs": [],
   "source": [
    "G_proj = ox.project_graph(G)\n",
    "nodes_proj = ox.graph_to_gdfs(G_proj, edges=False)\n",
    "graph_area_m = nodes_proj.unary_union.convex_hull.area\n",
    "graph_area_m"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6f99890",
   "metadata": {},
   "source": [
    "Rerunning new section"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb025a54",
   "metadata": {},
   "outputs": [],
   "source": [
    "import osmnx as ox\n",
    "import networkx as nx\n",
    "import geopandas as gpd\n",
    "import matplotlib.pyplot as plt\n",
    "plt.style.use('default')\n",
    "import pandas as pd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ee21787",
   "metadata": {},
   "outputs": [],
   "source": [
    "place_name = \"Paris, France\"\n",
    "graph = ox.graph_from_place(place_name, network_type='drive')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43a97c12",
   "metadata": {},
   "source": [
    "Default face color is:  (0.06666666666666667, 0.06666666666666667, 0.06666666666666667, 1.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c2f72aca",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "fig, ax = ox.plot_graph(graph)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "380ce71f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Retrieve only edges from the graph\n",
    "edges = ox.graph_to_gdfs(graph, nodes=False, edges=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25e1d836",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check columns\n",
    "edges.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d81ed110",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check crs\n",
    "edges.crs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "823635fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "edges.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9eedda7d",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(edges['highway'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a65b8074",
   "metadata": {},
   "outputs": [],
   "source": [
    "graph_proj = ox.project_graph(graph)\n",
    "fig, ax = ox.plot_graph(graph_proj)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bcf288e9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get Edges and Nodes\n",
    "nodes_proj, edges_proj = ox.graph_to_gdfs(graph_proj, nodes=True, edges=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b77020cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Coordinate system:\", edges_proj.crs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5ffeb659",
   "metadata": {},
   "outputs": [],
   "source": [
    "edges_proj.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbc7b5d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyproj import CRS\n",
    "CRS(edges_proj.crs).to_epsg()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ff5c5fe6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate network statistics\n",
    "stats = ox.basic_stats(graph_proj)\n",
    "stats"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "783cd8fe",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the Convex Hull of the network\n",
    "convex_hull = edges_proj.unary_union.convex_hull\n",
    "# Show output\n",
    "convex_hull"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fe4e7c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "graph_proj = ox.project_graph(graph)\n",
    "\n",
    "\n",
    "nodes_proj = ox.graph_to_gdfs(graph_proj, edges=False)\n",
    "graph_area_m = nodes_proj.unary_union.convex_hull.area\n",
    "graph_area_m\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e7c338ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate the area\n",
    "area = convex_hull.area\n",
    "\n",
    "# Calculate statistics with density information\n",
    "stats = ox.basic_stats(graph_proj, area=area)\n",
    "extended_stats = ox.basic_stats(graph_proj)\n",
    "\n",
    "# Add extened statistics to the basic statistics\n",
    "for key, value in extended_stats.items():\n",
    "    stats[key] = value\n",
    "\n",
    "# Convert the dictionary to a Pandas series for a nicer output\n",
    "pd.Series(stats)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f227a07",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the Convex Hull of the network\n",
    "convex_hull = edges_proj.unary_union.convex_hull\n",
    "\n",
    "# Centroid\n",
    "centroid = convex_hull.centroid\n",
    "\n",
    "# Show\n",
    "print(centroid)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ced974bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "nodes_proj.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ea09898d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the x coordinates of the nodes\n",
    "nodes_proj['x'] = nodes_proj[\"x\"].astype(float)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "393484fb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Retrieve the maximum x value (i.e. the most eastern)\n",
    "maxx = nodes_proj['x'].max()\n",
    "print(maxx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "334f1e9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Retrieve the node that is the most eastern one and get the Shapely Point geometry out of it\n",
    "target = nodes_proj.loc[nodes_proj['x']==maxx, 'geometry'].values[0]\n",
    "print(target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c51af6ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "cf = '[\"highway\"~\"motorway|motorway_link|trunk|trunk_link\"]'\n",
    "G = ox.graph_from_place(\"Madrid\", network_type=\"drive\", custom_filter=cf)\n",
    "fig, ax = ox.plot_graph(G, node_size=3,node_color='black',edge_linewidth=3,bgcolor='#FFFFFF')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ac6573c",
   "metadata": {},
   "outputs": [],
   "source": [
    "place = \"Madrid, Spain\"\n",
    "tags = {\"building\": True}\n",
    "gdf = ox.geometries_from_place(place, tags)\n",
    "fig, ax = ox.plot_footprints(gdf, figsize=(20, 20),alpha=1,color='black',bgcolor='#FFFFFF',save=True,filepath='settings.imgs_folder/image.png',show=True,dpi=600)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed9baa06",
   "metadata": {},
   "outputs": [],
   "source": [
    "import osmnx as ox\n",
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline \n",
    "place_name = 'Madrid,Spain'\n",
    "G = ox.graph_from_place(place_name,network_type=\"drive\")\n",
    "fig, ax = ox.plot_graph(G,figsize=(20,20),bgcolor='#FFFFFF',\n",
    "    node_color='black', node_size=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a86928e",
   "metadata": {},
   "outputs": [],
   "source": [
    "G = ox.graph_from_place(\n",
    "    \"Madrid, Spain\",network_type=\"all\",\n",
    "    retain_all=False,\n",
    "    truncate_by_edge=True,\n",
    "    simplify=True,\n",
    "    \n",
    ")\n",
    "\n",
    "fig, ax = ox.plot_graph(G, figsize=(20, 20),node_size=0, edge_color=\"#111111\", edge_linewidth=0.7,bgcolor='#FFFFFF')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4fbea616",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
